# -*- coding: utf-8 -*-
# 作者： 安智军
# @Time：2022/6/24 23:09
# @Email：1010666711@qq.com
# @File： 3、自动动手实现一个迭代器（实战）.py

'''
自己动手实现一个迭代器
思路：
1、迭代器的前提是个可迭代对象
2、迭代器比可迭代对象多了一个__next__方法 也有__iter__方法
3、__iter__方法返回self
4、__next__ 必须返回下一个值，如果没有则抛出StopIteration异常
5、对迭代器进行for进行操作时,每次都会执__next__方法 等价于执行 print(obj.__next__())
6、迭代器从头迭代到位只能迭代一次
7、for语句的迭代会忽略异常 StopIteration 迭代操作能用for 不要用while


# 迭代器不费内存 只能迭代一次  对list强制转化为迭代器 可以迭代多次
'''


# range（0,5） 1,2,3,4,5，
# Next（5） 1,2,3,4

# 使用迭代器实现range的方法
class Next(object):

    def __init__(self, stop, start=0):
        self.start = start
        self.stop = stop

    def __next__(self):
        '''
        返回下一个数，则返回下一个数，如果没有下一个数则抛出StopIteration异常
        :return:
        '''

        # 方法 一、先判断异常
        if self.start >= self.stop-1: # -1 临界值
            raise StopIteration
        self.start += 1  # 少写个else 可以优化代码
        return self.start

        # 后判断异常
        # if self.start < self.stop-1: # 判断有没有下一个数
        #     self.start += 1
        #     return self.start
        #
        # else:
        #     raise StopIteration

    def __iter__(self): # 每次调用next方法是先调用self
        return self


if __name__ == '__main__':
    obj = Next(5)


    # for i in obj: # TypeError: 'Next' object is not iterable  需要加一个 __iter__ 返回self方法就行
    #     print(i)
    #
    #
    # print(obj.__next__())  # 1
    # print(obj.__next__())  # 2
    # print(obj.__next__())  # 3
    # print(obj.__next__())  # 4
    # print(obj.__next__())  # 5

    obj1 = Next(5)
    for i, value in enumerate(obj1):
        print(i,value)

    '''
    0 1
    1 2
    2 3
    3 4
    '''
